package utils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import app.structure.Arg;

import com.vaadin.data.util.converter.Converter.ConversionException;
import com.vaadin.ui.AbstractField;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.DateField;
import com.vaadin.ui.TextField;

public class ViewComponentUtils {

	/**
	 * Retorna un Component de vaadin creat de un arg
	 * 
	 * @param arg
	 * @return AbstractField<?>
	 * @throws Exception
	 */
	public static AbstractField<?> createComponent(Arg arg) throws Exception {

		if (arg.getName() == null || arg.getType() == null)
			throw new Exception(
					"Excepcio en ViewComponentUTils.createComponent "
							+ arg.toString());

		AbstractField<?> af = null;

		String type = arg.getType().toLowerCase().trim();

		Class<?> myClass = getClassType(type);

		// si no te oritge de dades o si esta buit
		if (arg.getSource() == null || arg.getSource().isEmpty()) {

			switch (type) {
			case "date":
				DateField df = new DateField();

				df.setDateFormat("dd/MM/yy");
				df.setValue(DateUtils.parseDate(arg.getValue()));
				af = df;

				break;
			default:
				af = new TextField();
				((TextField) af).setValue(arg.getValue());
			}

		} else if (!arg.getEditor().isEmpty()) {

			switch (arg.getEditor().toLowerCase().trim()) {
			case "combo":
				ComboBox c = new ComboBox();
				for (String s : arg.getSource().split(","))
					c.addItem(s);
				c.setValue((arg.getValue().isEmpty()) ? "" : arg.getValue());
				af = c;
			case "tabla":

				break;
			case "checkbox":

				break;

			default:
				throw new Exception("Editor inexistent " + arg.getEditor());
			}

		}
		af.setConverter(myClass);
		af.setCaption(MessageUtils.getI18n(arg.getName()));
		return af;
	}

	/**
	 * Retorna un ArrayList<Arg> a partir de components i hashArgs
	 * 
	 * @param components
	 * @param hashArgs
	 * @return ArrayList<Arg>
	 * @throws Exception
	 */
	public static ArrayList<Arg> getArgs(List<AbstractField<?>> components,
			Collection<Arg> collection) throws Exception {

		Arg arg;
		AbstractField<?> af;

		ArrayList<Arg> args = new ArrayList<Arg>();

		Iterator<AbstractField<?>> itComponents = components.iterator();
		Iterator<Arg> itArgs = collection.iterator();

		while (itArgs.hasNext() && itComponents.hasNext()) {

			arg = itArgs.next();
			af = itComponents.next();
			String type = arg.getType().toLowerCase().trim();

			Object convertedValue = af.getConvertedValue();
			try {

				switch (type) {
				case "int":
					int integer = Integer.parseInt(convertedValue.toString());
					arg.setValue(Integer.toString(integer));
				case "float":
					float f = Float.parseFloat(convertedValue.toString());
					arg.setValue(Float.toString(f));
					break;
				case "date":
					arg.setValue(DateUtils.formatDate((Date) convertedValue));
					break;
				default:
					arg.setValue(convertedValue.toString());
					break;
				}

				args.add(arg);

			} catch (ConversionException e) {
				throw new Exception("error convertint");
			}

		}

		return args;
	}

	/**
	 * Retorna una Class a partir de tipo
	 * 
	 * @param type
	 * @return
	 */
	public static Class<?> getClassType(String type) {

		switch (type.toLowerCase().trim()) {
		case "date":
			return Date.class;
		case "int":
			return int.class;
		case "float":
			return float.class;
		default:
			return String.class;
		}
	}

}
